package de.uni_potsdam.hpi.bpt.ai.collection.impl;

import java.io.File;
import java.io.FilenameFilter;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import de.uni_potsdam.hpi.bpt.ai.collection.BPMAIExport;
import de.uni_potsdam.hpi.bpt.ai.collection.Model;
import de.uni_potsdam.hpi.bpt.ai.collection.ModelDirectory;


public class BPMAIExportImpl implements BPMAIExport{
	static String DATE_FORMAT = "yyyy-MM-dd";
	Set<ModelDirectoryImpl> directories = new HashSet<ModelDirectoryImpl>();
	Set<Model> models = new HashSet<Model>();
	
	public static final FilenameFilter FILENAME_FILTER = new FilenameFilter() {
		public boolean accept(File dir, String name) {
			return (!name.matches("^\\..*") &&
					!name.endsWith("metadata.json") &&
					(name.endsWith("json") ||
							name.endsWith("svg")) &&
					!name.equalsIgnoreCase("metadata.json"));
		}
	};
	
	public BPMAIExportImpl(File modelRootDirectory) {
		for (File workspaceDir : modelRootDirectory.listFiles()) {
			if (!workspaceDir.isDirectory()) {
				continue;
			}

			ModelDirectoryImpl s = handleWorkspace(workspaceDir);
			directories.add(s);

		}	
	}
	private ModelDirectoryImpl handleWorkspace(File workspaceDir) {
		ModelDirectoryImpl s = new ModelDirectoryImpl();
		s.setId(workspaceDir.getName());

		for (File group : workspaceDir.listFiles()) {
			if (!group.isDirectory()) {
				continue;
			}
			ModelGroupImpl modelGroup = new ModelGroupImpl();
			s.getGroups().add(modelGroup);
			handleModelGroup(group, modelGroup, s);
		}
		return s;
	}

	private void handleModelGroup(File group, ModelGroupImpl g, ModelDirectory s) {
		g.setName(group.getName());
		for (File modelDir : group.listFiles()) {
			if (!modelDir.isDirectory() || modelDir.getName().startsWith("_")) {
				continue;
			}
			Map<String, Model> idToModel = new LinkedHashMap<String, Model>();
			Map<String, RevisionImpl> revNumberToRevision = new HashMap<String, RevisionImpl>();

			DateFormat f = new SimpleDateFormat(DATE_FORMAT);
			String modelDirName = modelDir.getName();
			int index = modelDirName.indexOf("_");
			String modelName = modelDirName.substring(index + 1);
			String dateString = "";
			//String dateString = modelDirName.substring(0, index);
			if (index !=-1) {
				dateString = modelDirName.substring(0, index);	
			} else {
				dateString = modelName;
			}

			Date modelDate = null;
			try {
				modelDate = f.parse(dateString);
			} catch (ParseException e) {
				// invalid Date ignored
			}
			for (File file : modelDir.listFiles(FILENAME_FILTER)) {
				String name = file.getName();
				String modelId = name.split("_")[0];
				ModelImpl currentModel = (ModelImpl)idToModel.get(modelId);
				if(currentModel == null ){
					currentModel = new ModelImpl();
					currentModel.setId(modelId);
					currentModel.setName(modelName);
					currentModel.setDate(modelDate);
					idToModel.put(modelId, currentModel);
				}
				String[] refAndType = name.split("rev")[1].split("\\.");
				String ref = refAndType[0];
				String type = refAndType[1];
				RevisionImpl r = revNumberToRevision.get(modelId +""+ref);
				if (r == null) {
					r = new RevisionImpl();
					r.setNumber(Integer.parseInt(ref));
					revNumberToRevision.put(modelId +""+ref, r);
					currentModel.getRevisions().add(r);

				}
				if (type.equalsIgnoreCase("svg")) {
					r.setSvg(file);
				} else if (type.equalsIgnoreCase("json")) {
					r.setJson(file);
				}

			}
			g.setModels(idToModel.values());
			models.addAll(g.getModels());
		}
	}
	/* (non-Javadoc)
	 * @see org.oryxproject.bpm_ai.impl.BPMAIExport#getDirectories()
	 */
	@Override
	public Collection<ModelDirectoryImpl> getDirectories() {
		return Collections.unmodifiableSet(directories);
	}
	/* (non-Javadoc)
	 * @see org.oryxproject.bpm_ai.impl.BPMAIExport#getModels()
	 */
	@Override
	public Set<Model> getModels() {
		return Collections.unmodifiableSet(models);
	}
	/* (non-Javadoc)
	 * @see org.oryxproject.bpm_ai.impl.BPMAIExport#iterator()
	 */
	@Override
	public Iterator<Model> iterator() {
		return models.iterator();
	}
}
